之前一直的调试一直是使用 runserver 命令来运行,这篇博客记录一下我们写好的django博客如何利用nginx和uwsgi部署于生产环境中。
nginx、wsgi、django 三者关系:
我的理解:wsgi 所扮演的的角色是后端 http 服务器,nginx 扮演的角色是前端 http 服务器,django项目 是客户所真正要访问到的提供数据方。用户从网页浏览器中发出请求,nginx 会一直监听某个(通常是80或者443)端口,收到请求后,反向解析代理将用户的请求转发给 uwsgi 服务器,uwsgi 服务器通过django处理完毕后将结果返回给 nginx,浏览器将最终的结果展现给用户。服务器对外的可以只暴露 80 和 443 端口。
部署前,我们的项目是这样运行的,我们需要保证这样运行时是没有问题的,有错误的话就根据错误修改:
python3 manage.py runserver 127.0.0.1:8080
部署过程:
一、uwsgi安装配置
1、安装
pip3 install uwsgi
2、创建配置文件 uwsgi.ini
在工程目录里创建 uwsgi.ini 配置文件,内容大体如下:
[uwsgi]
http = :xxxx
#django 端口号
socket = 127.0.0.1:8001
#django 目录
chdir = /xxx/xxx/xxx
#虚拟环境路径
virtualenv = /root/.virtualenvs/xxxx_venv/
#Django 项目下 wsgi.py 文件路径
module = xxxx.wsgi
#主进程
master = true
#进程数
processes = 1
#服务器退出的时候自动清理环境
vacuum = true
#日志记录
daemonize = uwsgi/UWSGI.log
#记录状态服务
stats = uwsgi/uwsgi.status
#指定pid文件的位置,记录主进程的pid号。
pidfile = uwsgi/uwsgi.pid
相关参数以及解释大体如下:
# 服务相关操作
uwsgi --ini uwsgi.ini # 启动
uwsgi --reload uwsgi.pid # 重启
uwsgi --stop uwsgi.pid # 关闭
uwsgi --connect-and-read uwsgi/uwsgi.status #读取uwsgi实时状态
# 配置字段相关说明
socket : 地址和端口号,例如:socket = 127.0.0.1:50000
processes : 开启的进程数量
workers : 开启的进程数量,等同于processes(官网的说法是spawn the specified number of workers / processes)
chdir : 指定运行目录(chdir to specified directory before apps loading)
wsgi-file : 载入wsgi-file(load .wsgi file)
stats : 在指定的地址上,开启状态服务(enable the stats server on the specified address)
threads : 运行线程。由于GIL的存在,我觉得这个真心没啥用。(run each worker in prethreaded mode with the specified number of threads)
master : 允许主进程存在(enable master process)
daemonize : 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器(daemonize uWSGI)。实际上最常用的,还是把运行记录输出到一个本地文件上。
log-maxsize :以固定的文件大小(单位KB),切割日志文件。 例如:log-maxsize = 50000000 就是50M一个日志文件。
pidfile : 指定pid文件的位置,记录主进程的pid号。
vacuum : 当服务器退出的时候自动清理环境,删除unix socket文件和pid文件(try to remove all of the generated file/sockets)
disable-logging :
不记录请求信息的日志。只记录错误以及uWSGI内部消息到日志中。如果不开启这项,那么你的日志中会大量出现这种记录:
[pid: 347|app: 0|req: 106/367] 117.116.122.172 () {52 vars in 961 bytes} [Thu Jul 7 19:20:56 2016] POST /post => generated 65 bytes in 6 msecs (HTTP/1.1 200) 2 headers in 88 bytes (1 switches on core 0)
log-maxsize: 日志大小,当大于这个大小会进行切分 (Byte)
log-truncate: 当启动时切分日志
3、 开启服务
执行一下命令,读取配置,开启服务
uwsgi --ini uwsgi.ini
二、nginx安装配置
1、安装nginx
apt install nginx
2、配置nginx
我习惯自己新建一个mysite.conf文件,位置在 /etc/nginx/conf.d/ 下。相关配置如下:
server {
listen 80; # nginx 监听端口号
server_name example.com;
charset UTF-8;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
client_max_body_size 75M;
location /static {
# 静态文件配置
root /home/ubuntu/mysite;
}
location /media {
# 媒体文件配置
root /home/ubuntu/mysite;
}
location / {
# 这个地址和uwsgi.ini里面的socket配置一致!
uwsgi_pass 127.0.0.1:8001;
include uwsgi_params;
}
}
上述一个配置可以实现http 80 端口的访问,如果是https 443端口,大体调地配置文件格式如下:
server {
# 监听 https 443端口
listen 443 ssl;
server_name example.com;
ssl on; #开启ssl
ssl_certificate cert/*.pem; #pem 位置
ssl_certificate_key cert/*.key; #key 位置
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#密码加密方式
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
#依赖SSLv3和TLSv1协议的服务器密码将优先于客户端密码
ssl_prefer_server_ciphers on;
#静态文件处理
location /static {
alias /home/www/work/project/pro/;
#媒体文件处理
location /media {
alias /home/www/work/project/pro/;
其他文件转wsgi处理
location / {
#这个是uwsgi.ini中配置的 socket
uwsgi_pass x.x.x.x:xxxx;
include uwsgi_params;
}
}
#配置80端口重定向到https 443
server {
listen 80;
server_name example.com;
rewrite ^(.*)$ https://$host$1 permanent;
}
3、开启nginx服务
首先nginx相关的命令如下:
apt install nginx //安装
nginx -v // 查看版本
nginx -c //设置默认的配置文件
nginx -t //检查nginx配置是否语法错误
nginx -s reload //重新加载
nginx -s reopen //重启
nginx -s stop //关闭
service nginx start //启动服务
service nginx stop // 关闭服务
service nginx restart //重启服务
创建了自己的配置文件之后,可以执行 nginx -c xxxxx 来指定为默认的配置文件。nginx -t 可以检查语法错误等。最后nginx -s reload 重启nginx 服务即可。到此,不出意外的话,你应该访问网站的80端口会看到你的博客!大家快来试试吧!
配置中遇到的问题:
1、访问网页80端口或者443端口无法访问?
要确保那你的服务器的防火墙,有没有放通80端口或者443端口。
2、访问网页80端口一直提示 welcome to nginx 界面?
这个很坑,你需要修改 /etc/nginx/nginx.conf 文件,找到下面一句注释掉,重启服务再试下:
include /etc/nginx/sites-enabled/*;
3、返回网页为server Error 500 ?
一般是你的django代码有问题,建议先用manage runserver 调试好再部署。
4、记得部署后,把你的settings.py文件中的 debug 选项改为 False
《django 建站历程系列文章》